#title: Hello world
#index:0,3
#author:zozoh(zozohtnt@gmail.com)

--------------------------------------------------------------------------------------------------------
 Ioc 的概念
	Nutz.Ioc 从概念上是很简单：将一部分关于对象的依赖关系单独存储在某种介质里，并且
	提供一个接口帮助使用者获得这些对象。

	但是将依赖关系存储在什么地方呢？ Spring 选的是 XML， Guice 选的 Java （硬编码）
	
	Nutz.Ioc 核心逻辑并没有限定配置信息的存储方式，但它还是提供了一个默认的配置文件
	编写方式 -- JSON。因为
	 * 省却了 XML 书写的烦恼
	 * 避免了硬编码 -- 修改配置，不需要重新编译工程
	
	当然，你可以扩展它，提供自己的配置文件加载方式， Nutz.Ioc 不反对你这样，它甚至
	有点鼓励你这样，虽然 JSON 方式的配置文件书写方式已经工作的很好了。
	 
	下面，我先以 JSON 文件为例，给大家一个 Hello World

--------------------------------------------------------------------------------------------------------
一个简单的例子
	在这个例子中，你需要一 POJO，以及一个 JSON 配置文件。
	例子的源代码，你可以访问 [http://nutzdemo.googlecode.com]  获取
	
	POJO 源代码
		{{{
		package nutz.demo.ioc.book;
		
		import java.util.Calendar;

		public class Pet {

			private String name;

			private Calendar birthday;

			private Pet friend;

			public Pet() {}

			public Pet(String name) {
				this.name = name;
			}

			public String getName() {
				return name;
			}

			public void setName(String name) {
				this.name = name;
			}

			public Calendar getBirthday() {
				return birthday;
			}

			public void setBirthday(Calendar birthday) {
				this.birthday = birthday;
			}

			public Pet getFriend() {
				return friend;
			}

			public void setFriend(Pet friend) {
				this.friend = friend;
			}
		}
		}}}
		这个对象有两个构造函数
	
	Json 配置文件
		与 POJO 在同一包路径下
		{{{
		/*
		 * 开始写上 var ioc = { ， 是为了利用 eclipse 的  javascript 编辑器的自动格式化功能
		 */
		var ioc = {
			/*
			 * 默认的，你仅仅需要直接声明每个字段的值即可，Nutz.Ioc 会为你转型
			 */
			xiaobai : {
				name : 'XiaoBai',
				birthday : '2009-10-25 15:23:40'
			},
			/*
			 * 你当然也可以做更细致的设置
			 */
			xiaohei : {
				type : 'nutz.demo.ioc.book.Pet', // 类型
				singleton : false, // 是否为单件
				args : [ 'XiaoHei' ], // 构造函数参数
				fields : {
					birthday : '2009-11-3 08:02:14',
					friend : {refer : 'xiaobai'}	// 指向容器里另外一个对象
				}
			}
		}
		}}}
		
	调用代码
		{{{
		package nutz.demo.ioc.book;

		import org.nutz.ioc.Ioc;
		import org.nutz.ioc.impl.NutIoc;
		import org.nutz.ioc.loader.json.JsonLoader;

		public class HelloPet {

			public static void main(String[] args) {
				Ioc ioc = new NutIoc(new JsonLoader("nutz/demo/ioc/pet/pets.js"));
				Pet pet = ioc.get(Pet.class, "xiaobai");
				System.out.printf("%s - [%s]\n", pet.getName(), pet.getBirthday().getTimeZone().getID());
			}

		}
		}}}
	控制台输出
		{{{
		XiaoBai - [Asia/Shanghai]
		}}}
	
	如果配置文件中声明了类型，则可不传入类型
		{{{
		Pet xh = ioc.get(null, "xiaohei");
		System.out.printf("%s's friend is %s\n", xh.getName(), xh.getFriend().getName());
		}}}
		控制台输出：
		{{{
		XiaoHei's friend is XiaoBai
		}}}
	
	声明了 singleton: false，那么它每次获取，都会生成一个新的实例
		{{{
		Pet p1 = ioc.get(null, "xiaohei");
		Pet p2 = ioc.get(null, "xiaohei");
		System.out.println(p1==p2);
		}}}
		控制台输出：
		{{{
		false
		}}}

--------------------------------------------------------------------------------------------------------
关于进阶
	我可以负责任的告诉你：你已经掌握了 Nutz.Ioc 在你开发的时候 80% 情况下所需要的知识。
	当然，它还提供了更多的功能，有些功能是其他 Ioc 容器所不具备的，你可以根据自己需要来阅读，他们包括：
	
	 * [inner_object.man 匿名对象]
	 * [events.man 事件监听]
	 * [injecting.man 你都可以注入什么]
	 * [events.man 事件的监听]
	 * [ioc_loader.man 定义自己的配置文件格式]
	 * [../aop/aop_solution.man AOP模型] -- NutAop的实现思路
	 * [../aop/aop.man AOP] -- 声明式切片
	 * [scope.man 对象生命范围] -- 级联的上下文环境
	 * [xml_ioc_loader.man 使用XML作为配置文件格式] -- 使用XML作为配置文件格式
	 * [loader_annotation.man 使用注解配置Ioc] --使用注解配置Ioc
	 * [../aop/aop_json.man 用json文件声明Aop切片] -- 在json配置文件中声明Aop及声明式事务
	 
--------------------------------------------------------------------------------------------------------
关于工厂方法

	从1.b.51开始, nutz内置的json/xml/annotation加载器支持工厂方法了
	
	Json写法是
	
	{{{
		{
			ssdb : {
				type : "org.nutz.ssdbj4.spi.SSDB", // 接口或抽象类
				args : ["127.0.0.1", 8888, 5000, null],
				factory : "org.nutz.ssdbj4.SSDBs#pool" // 类名#方法名
			}
		}
	}}}
	
	XML写法是
	
	{{{
		<ioc>
			<obj name="ssdb" type="org.nutz.ssdbj4.spi.SSDB" factory="org.nutz.ssdbj4.SSDBs#pool">
				<args>
					<str>127.0.0.1</refer>
					<int>8888</int>
					<int>5000</int>
				</args>
			</obj>
		</ioc>
	}}}

--------------------------------------------------------------------------------------------------------
可选属性

	从1.b.51开始, nutz内置的json/xml/annotation加载器支持可选属性了
	
	有时候,某些服务即使不存在也不会影响系统的运行,但这些属性又是ioc配置好的,这时就需要可选属性了
	
	注解的写法是
	
	{{{
		@IocBean
		public class MqttService {
		
			@Inject(optional=true)
			protect Dao dao;
			
			@Inject
			protect MqttClient client;
			
			public void publish(String topic, Object data) {
				if (dao != null) { // 有就记录,没有就算了呗
					dao.insert(new MqttHistory(topic, String.value(data));
				}
				client.publish(topic, data);
			}
		}
	}}}